package bsc.war.form;

import bsc.ejb.entity.ColorimetrySettings;
import bsc.ejb.entity.Comparator;
import bsc.ejb.entity.Dimension;
import bsc.ejb.entity.DimensionMember;
import bsc.ejb.entity.DimensionalCut;
import bsc.ejb.entity.DimensionalCutMember;
import bsc.ejb.entity.Person;
import bsc.ejb.entity.Pointer;
import bsc.ejb.entity.ScoreCard;
import bsc.ejb.entity.ScoreCardDimension;
import bsc.ejb.entity.Settings;
import bsc.ejb.metadata.Colorimetry;
import bsc.ejb.metadata.Comparation;
import bsc.ejb.metadata.Framework;
import bsc.war.delegate.DelegateBSC;
import bsc.war.factory.Factory;
import bsc.war.service.ScoreCardUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
 *
 * @author memozac
 */
public class NewPointer extends AbstractController {

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        try {
            DelegateBSC delegate = (DelegateBSC) Factory.getBean("DelegateBSC");

            Framework framework = delegate.findFramework(Boolean.TRUE);

            //ScoreCardRelation scoreCardRelation = (ScoreCardRelation) Factory.getBean("ScoreCardRelation");

            Long idScoreCard = request.getParameter("idScoreCard") != null && NumberUtils.isNumber(request.getParameter("idScoreCard")) ? Long.parseLong(request.getParameter("idScoreCard")) : null;
            Long idPerson = request.getParameter("person") != null && NumberUtils.isNumber(request.getParameter("person")) ? Long.parseLong(request.getParameter("person")) : null;
            
            String[] dimensionIds = {"1"};
            String[] dimensionalCuts = {"1"};

            if(request.getParameterValues("dimension")!=null && request.getParameterValues("dimensionalCut")!=null){
                dimensionIds=request.getParameterValues("dimension");
                dimensionalCuts=request.getParameterValues("dimensionalCut");
            }

            ScoreCard scoreCard = idScoreCard != null ? delegate.findScoreCard(idScoreCard) : null;
            Boolean edit = scoreCard != null;
            request.setAttribute("edit", edit);

            //pointer
            Pointer pointer = edit ? (Pointer) scoreCard : (Pointer) Factory.getBean("Pointer");
            pointer.setDescription(request.getParameter("description"));
            pointer.setName(request.getParameter("name"));
            pointer.setUnit(request.getParameter("unit"));
            Person person = delegate.findPerson(idPerson);
            pointer.setResponsible(person);

            if (edit) {
                delegate.updatePointer(pointer);
            } else {
                delegate.createPointer(pointer);
            }

            //dimensions
            if (!edit) {
                for (String idDimension : dimensionIds) {
                    Dimension d = delegate.findDimension(Long.parseLong(idDimension));
                    if (delegate.findScoreCardDimension(idScoreCard) == null) {
                        ScoreCardDimension scorecardDimension = (ScoreCardDimension) Factory.getBean("ScoreCardDimension");
                        scorecardDimension.setScoreCard(pointer);
                        scorecardDimension.setDimension(delegate.findDimension(Long.parseLong(idDimension)));
                        delegate.createScoreCardDimension(scorecardDimension);
                    }
                }
            }


            //comparators - Settings of the comparator
            Comparator comparatorReal = null;
            //System.out.println("COMMAND: " + request.getParameter("command"));
            Settings.Command command = Settings.Command.valueOf(request.getParameter("command"));
            List<Comparation> comparations = delegate.findComparation(framework, Boolean.TRUE);
            if (comparations != null && comparations.size() > 0) {
                for (Comparation comparation : comparations) {
                    //Comparator comparator = (Comparator) Factory.getBean("Comparator");
                    //System.out.println("Indicador a editar: " + pointer.getName());
                    //System.out.println("Comaparador del tipo: " + comparation.getName());
                    Comparator comparator = edit ? delegate.findComparator(pointer, comparation) : (Comparator) Factory.getBean("Comparator");

                    comparator.setDescription(comparation.getName());
                    comparator.setPointer(pointer);
                    comparator.setComparation(comparation);

                    if (edit) {
                        delegate.updateComparator(comparator);
                    } else {
                        delegate.createComparator(comparator);
                    }



                    // comparator.setDescription(comparation.getName());

                    //comparator settings
                    Settings comparatorSettings = edit ? comparator.getSettings() : (Settings) Factory.getBean("Settings");

                    comparatorSettings.setCommand(command);
                    comparatorSettings.setType(Settings.Type.COMPARATOR);
                    comparatorSettings.setComparator(comparator);

                    if (edit) {
                        delegate.updateSettings(comparatorSettings);
                    } else {
                        delegate.createSettings(comparatorSettings);
                    }


                    comparator.setSettings(comparatorSettings);
                    delegate.updateComparator(comparator);

                    if (comparation.getType() == Comparation.Type.REAL) {
                        comparatorReal = comparator;
                    }
                }
            }

            //pointer settings
            Settings pointerSettings = edit ? pointer.getSettings() : (Settings) Factory.getBean("Settings");
            pointerSettings.setScoreCard(pointer);


            String zeroTrendValue = request.getParameter("zeroTrendValue") != null && NumberUtils.isNumber(request.getParameter("zeroTrendValue")) ? request.getParameter("zeroTrendValue") : "1";
            pointerSettings.setZeroTrendValue(zeroTrendValue);

            //Math Operation
            String mathOperation = request.getParameter("mathOperation");
            String finalMathOperation = "";
            String finalSpecialOperation = "";
            if (Settings.Polarity.valueOf(mathOperation) == Settings.Polarity.HIGH) {
                finalMathOperation = "C" + comparatorReal.getIdComparator() + "/P";
            } else if (Settings.Polarity.valueOf(mathOperation) == Settings.Polarity.LOW) {
                finalMathOperation = "P/" + "C" + comparatorReal.getIdComparator();
            } else if (Settings.Polarity.valueOf(mathOperation) == Settings.Polarity.SPECIAL) {
                finalMathOperation = "C" + comparatorReal.getIdComparator() + "/P";
                finalSpecialOperation = "2-(C" + comparatorReal.getIdComparator() + "/P)";
            } else if (Settings.Polarity.valueOf(mathOperation) == Settings.Polarity.ZERO_TREND) {
                finalMathOperation = "(C" + comparatorReal.getIdComparator() + "-" + zeroTrendValue + ")/(P-" + zeroTrendValue + ")";
            } else if(Settings.Polarity.valueOf(mathOperation) == Settings.Polarity.ZERO_TREND_SPECIAL){
                finalMathOperation = "(C" + comparatorReal.getIdComparator() + "-" + zeroTrendValue + ")/(P-" + zeroTrendValue + ")";
                finalSpecialOperation = "2-((C" + comparatorReal.getIdComparator() + "-" + zeroTrendValue + ")/(P-" + zeroTrendValue + "))";
            }

            pointerSettings.setMathOperation(finalMathOperation);
            pointerSettings.setSpecialOperation(finalSpecialOperation);

            //TYPE CALCULATE
            String operationData = request.getParameter("operationData");
            pointerSettings.setOperationData(Settings.OperationData.valueOf(operationData));

            String dimensionalCutOperation = request.getParameter("dimensionalCutOperation");
            pointerSettings.setDimensionalCutOperation(dimensionalCutOperation);


            //System.out.println("TEMPORALIDAD: " + request.getParameter("temporality"));
            pointerSettings.setTemporality(Settings.Temporality.valueOf(request.getParameter("temporality")));
            pointerSettings.setType(Settings.Type.SCORECARD);
            Settings.Frecuency frecuency = Settings.Frecuency.valueOf(request.getParameter("frecuency"));
            pointerSettings.setFrecuency(frecuency);
            Settings.Polarity polarity = Settings.Polarity.valueOf(mathOperation);
            pointerSettings.setPolarity(polarity);
            pointerSettings.setRegisterDate(ScoreCardUtils.generateDate(request.getParameter("startDate")));

            if (edit) {
                delegate.updateSettings(pointerSettings);
            } else {
                delegate.createSettings(pointerSettings);
            }

            pointer.setSettings(pointerSettings);
            delegate.updatePointer(pointer);

            //personScoreCard

            /*PersonScoreCard personScoreCard = (PersonScoreCard) Factory.getBean("PersonScoreCard");
            Person person = delegate.findPerson(idPerson);
            personScoreCard.setPerson(person);
            personScoreCard.setScoreCard(pointer);
            delegate.createPersonScoreCard(personScoreCard);*/




            //scoreCardRelation
            /*scoreCardRelation.setScoreCard(scoreCard);
            scoreCardRelation.setOtherScoreCard(pointer);
            delegate.createScoreCardRelation(scoreCardRelation);*/

            //colorimetries

            List<Colorimetry> colorimetries = delegate.findColorimetry(framework, Boolean.TRUE);
            if (colorimetries != null && colorimetries.size() > 0) {
                for (Colorimetry colorimetry : colorimetries) {
                    ColorimetrySettings colorimetrySettings = edit ? delegate.findColorimetrySettings(colorimetry, pointerSettings) : (ColorimetrySettings) Factory.getBean("ColorimetrySettings");
                    String minValue = request.getParameter("min_value_colorimetry_" + colorimetry.getIdColorimetry());
                    String maxValue = request.getParameter("max_value_colorimetry_" + colorimetry.getIdColorimetry());
                    Double maxDob = (NumberUtils.isNumber(maxValue) ? Double.parseDouble(maxValue) : Double.valueOf(maxValue)) / 100;
                    Double minDob = (NumberUtils.isNumber(minValue) ? Double.parseDouble(minValue) : Double.valueOf(minValue)) / 100;
                    colorimetrySettings.setMaxScore(maxDob);
                    colorimetrySettings.setMinScore(minDob);
                    colorimetrySettings.setSettings(pointerSettings);
                    colorimetrySettings.setColorimetry(colorimetry);
                    if (colorimetrySettings != null) {
                        delegate.updateColorimetrySettings(colorimetrySettings);
                    } else {
                        delegate.createColorimetrySettings(colorimetrySettings);
                    }
                }
            }


            //dimensionalcuts

            /*
            if (!edit) {
                if (dimensionalCuts != null && dimensionalCuts.length > 0) {
                    for (String dimensionalMembers : dimensionalCuts) {
                        DimensionalCut dimensionalCut = (DimensionalCut) Factory.getBean("DimensionalCut");
                        dimensionalCut.setPointer(pointer);
                        dimensionalCut.setType(DimensionalCut.Type.STANDARD);
                        delegate.createDimensionalCut(dimensionalCut);
                        System.out.println("Puede crear un corte");
                        boolean isTotal = true;
                        String[] dimensionMembers = dimensionalMembers.split("_");
                        for (String idDimensionMember : dimensionMembers) {
                            if (NumberUtils.isNumber(idDimensionMember)) {
                                DimensionalCutMember dimensionalCutMember = (DimensionalCutMember) Factory.getBean("DimensionalCutMember");
                                DimensionMember dimensionMember = delegate.findDimensionMember(Long.parseLong(idDimensionMember));

                                if (dimensionMember.getType() == DimensionalCut.Type.STANDARD) {
                                    isTotal = false;
                                }

                                dimensionalCutMember.setDimensionMember(dimensionMember);
                                dimensionalCutMember.setDimensionalCut(dimensionalCut);


                                delegate.createDimensionalCutMember(dimensionalCutMember);
                                System.out.println("DimensionalCutMember (Dimensional Cut): " + dimensionalCutMember.getDimensionalCut().getIdScoreCard());
                                System.out.println("DimensionalCutMember (ID): " + dimensionalCutMember.getIdDimensionalCutMember());

                                System.out.println("El dimensionmember es: " + dimensionMember.getName());
                                System.out.println("Pude crear un dimensionalcutmember");
                            }
                        }
                        if (isTotal) {
                            dimensionalCut.setType(DimensionalCut.Type.TOTAL);
                            delegate.updateDimensionalCut(dimensionalCut);
                        }
                        

                    }
                }*/

            //List of dimensionalCuts
            
            
            List<DimensionalCut> dimensionalCutsDB = new ArrayList<DimensionalCut>();
            Long dimensionalCutTotal = null;

            if (!edit) {
                if (dimensionalCuts != null && dimensionalCuts.length > 0) {
                    for (int i =0; i < dimensionalCuts.length; i++) {
                        DimensionalCut dimensionalCut = (DimensionalCut) Factory.getBean("DimensionalCut");
                        dimensionalCut.setPointer(pointer);
                        dimensionalCut.setType(DimensionalCut.Type.STANDARD);
                        delegate.createDimensionalCut(dimensionalCut);
                        dimensionalCutsDB.add(dimensionalCut);
                    }
                    for (int i =0; i < dimensionalCuts.length; i++) {

                        boolean isTotal = true;

                        DimensionalCut dimensionalCut = dimensionalCutsDB.get(i);
                        
                        String dimensionalMembers =  dimensionalCuts[i];
                        String[] dimensionMembers = dimensionalMembers.split("_");
                        for (String idDimensionMember : dimensionMembers) {
                            if (NumberUtils.isNumber(idDimensionMember)) {
                                DimensionalCutMember dimensionalCutMember = (DimensionalCutMember) Factory.getBean("DimensionalCutMember");
                                DimensionMember dimensionMember = delegate.findDimensionMember(Long.parseLong(idDimensionMember));

                                if (dimensionMember.getType() == DimensionalCut.Type.STANDARD) {
                                    isTotal = false;
                                }

                                dimensionalCutMember.setDimensionMember(dimensionMember);
                                dimensionalCutMember.setDimensionalCut(dimensionalCut);


                                delegate.createDimensionalCutMember(dimensionalCutMember);
                                
                            }
                        }

                        if (isTotal) {
                            dimensionalCutTotal = dimensionalCut.getIdScoreCard();
                        }

                    }

                    //Se asigna el TOTAL
                    if(dimensionalCutTotal != null){
                        DimensionalCut dimensionalCutTotalObject = delegate.findDimensionalCut(dimensionalCutTotal);
                        dimensionalCutTotalObject.setType(DimensionalCut.Type.TOTAL);
                        delegate.updateDimensionalCut(dimensionalCutTotalObject);
                    }
                    
                }

            }


        } catch (Exception e) {
            System.err.println("Caught exception: " + e);
            e.printStackTrace();
        }

        return new ModelAndView("newPointer");
    }
}
